package com.dd.cloud.user.service.admin.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.constants.AdminConstants;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.DateUtils;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.common.vo.PageVo;
import com.dd.cloud.user.entity.admin.AdminSaleInfo;
import com.dd.cloud.user.entity.admin.SaleInviteDoctor;
import com.dd.cloud.user.mapper.admin.SaleInviteDoctorMapper;
import com.dd.cloud.user.req.admin.*;
import com.dd.cloud.user.res.admin.*;
import com.dd.cloud.user.service.admin.IAdminSaleInfoService;
import com.dd.cloud.user.service.admin.IAdminUserService;
import com.dd.cloud.user.service.admin.ISaleInviteDoctorService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Lx
 * @version 1.0
 */
@Slf4j
@Service
public class SaleInviteDoctorServiceImpl extends ServiceImpl<SaleInviteDoctorMapper, SaleInviteDoctor> implements ISaleInviteDoctorService {
    @Autowired
    private IAdminUserService adminUserService;
    @Autowired
    private IAdminSaleInfoService adminSaleInfoService;

    /**
     * 批量添加
     */
    @Override
    public void saveBatchByList(List<SaleInviteDoctor> list) {
        Integer column = getBaseMapper().insertBatchSomeColumn(list);
        if (column <= 0) {
            throw new ZekeException("批量添加销售绑定医生失败");
        }
    }

    /**
     * 查询销售邀请医生列表
     *
     * @param req
     * @return
     */
    @Override
    public PageVo<SaleInviteDoctorPageRes> querySaleInviteDoctorPage(SaleInviteDoctorPageReq req) {
        if (req.verify()) {
            throw new ZekeException(400, "日期参数错误");
        }
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        Integer adminType = adminUserService.getAdminUserType(loginInfo.getId());
        if (req.getSaleId() == null) {
            req.setSaleId(loginInfo.getId());
            if (adminType != AdminConstants.UserType.SALE) {
                throw new ZekeException(400, "销售id不能为空");
            }
        }
        if (loginInfo.getId() == 61 && loginInfo.getType() == LoginInfo.UserType.ADMIN){
            //是山东五莲的兼职销售刘贵林, 特殊处理, 查询山东五莲县的医生 机构ID写死
            req.setSaleId(null);
            req.setMechanId(78);
        }
        if (req.getCountStatus() == null) {
            req.setCountStatus(1);
        } else {
            req.setCountStatus(-1);
        }
        PageVo<SaleInviteDoctorPageRes> pageVo = req.pageVoPojo();
        pageVo = getBaseMapper().querySaleInviteDoctorPage(pageVo, req);
        if (req.getIsStatistics() == 1) {
            List<SaleInviteCountRes> countList = getBaseMapper().querySaleInviteCount(req);
            pageVo.setExtend(countList);
            String year = LocalDate.now().getYear() + "年";
            for (SaleInviteCountRes item : countList) {
                item.setMonth(item.getMonth().replace(year, ""));
            }
        }
        for (SaleInviteDoctorPageRes item : pageVo.getRecords()) {
            if (item.getIsAuth() == null && item.getIsCertification() == 1) {
                item.setIsAuth(2);
            }
            item.setIsAuth(item.getIsAuth() == null ? 0 : item.getIsAuth());

        }
        return pageVo;
    }

    /**
     * 绑定销售邀请的医生
     *
     * @param inviteCode
     * @param doctorId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AdminSaleInfo bindSaleInviteDoctor(String inviteCode, Integer doctorId) {
        QueryWrapper<AdminSaleInfo> qw = new QueryWrapper<>();
        qw.lambda().eq(AdminSaleInfo::getInviteCode, inviteCode);
        qw.lambda().ne(AdminSaleInfo::getStatus, AdminConstants.SaleInfoStatus.DEL);
        AdminSaleInfo adminSaleInfo = adminSaleInfoService.getOne(qw);
        if (adminSaleInfo == null) {
            throw new ZekeException(400, "邀请码不存在,请重新输入");
        }
        SaleInviteDoctor saleInviteDoctor = new SaleInviteDoctor();
        saleInviteDoctor.setDoctorId(doctorId);
        saleInviteDoctor.setSaleId(adminSaleInfo.getAdminId());
        saleInviteDoctor.setStatus(AdminConstants.SaleInviteStatus.NORMAL);
        saleInviteDoctor.setCreateDate(LocalDateTime.now());
        save(saleInviteDoctor);
        return adminSaleInfo;
    }

    /**
     * 销售统计邀请已认证医生开方数据
     *
     * @param req
     * @return
     */
    @Override
    public PageVo<SaleInviteDoctorStatisticsAuthPageRes> querySaleInviteDoctorStatisticsAuthPage(SaleInviteDoctorStatisticsAuthPageReq req) {
        PageVo<SaleInviteDoctorStatisticsAuthPageRes> pageVo = req.pageVoPojo();
        pageVo = getBaseMapper().querySaleInviteDoctorStatisticsAuthPage(pageVo, req);
        if (req.getIsStatistics() == 1) {
            List<SaleInviteCountRes> countList = getBaseMapper().querySaleInviteStatisticsAuthCount(req);
            pageVo.setExtend(countList);
            String year = LocalDate.now().getYear() + "年";
            for (SaleInviteCountRes item : countList) {
                item.setMonth(item.getMonth().replace(year, ""));
            }
        }
        return pageVo;
    }

    /**
     * 销售统计邀请未认证医生开方数据
     *
     * @param req
     * @return
     */
    @Override
    public PageVo<SaleInviteDoctorStatisticsNoAuthPageRes> querySaleInviteDoctorStatisticsNoAuthPage(SaleInviteDoctorStatisticsNoAuthPageReq req) {
        PageVo<SaleInviteDoctorStatisticsNoAuthPageRes> pageVo = req.pageVoPojo();
        pageVo = getBaseMapper().querySaleInviteDoctorStatisticsNoAuthPage(pageVo, req);
        if (req.getIsStatistics() == 1) {
            List<SaleInviteCountRes> countList = getBaseMapper().querySaleInviteStatisticsNoAuthCount(req);
            pageVo.setExtend(countList);
            String year = LocalDate.now().getYear() + "年";
            for (SaleInviteCountRes item : countList) {
                item.setMonth(item.getMonth().replace(year, ""));
            }
        }
        return pageVo;
    }

    /**
     * 销售查询邀请医生订单列表
     *
     * @param req
     * @return
     */
    @Override
    public IPage<SaleInviteDoctorOrderPageRes> querySaleInviteDoctorOrderPage(SaleInviteDoctorOrderPageReq req) {
        if (req.verify()) {
            throw new ZekeException(400, "日期参数错误");
        }
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        Integer adminType = adminUserService.getAdminUserType(loginInfo.getId());
        if (req.getSaleId() == null) {
            req.setSaleId(loginInfo.getId());
            if (adminType != AdminConstants.UserType.SALE && adminType != AdminConstants.UserType.ADMIN && adminType != AdminConstants.UserType.PLAIN) {
                throw new ZekeException(400, "销售id不能为空");
            }
        }
        if (loginInfo.getId() == 61 && loginInfo.getType() == LoginInfo.UserType.ADMIN){
            //是山东五莲的兼职销售刘贵林, 特殊处理, 查询山东五莲县的医生订单 机构ID写死
            req.setSaleId(null);
            req.setMechanId(78);
        }
        if (StringUtils.isBlank(req.getStatus())) {
            req.setStatus("0,1,11,12,2,21,3,8,9");
        }
        if (StringUtils.isBlank(req.getOrderStatus())) {
            req.setOrderStatus("-2,-1,2,1,4");
        }
        IPage<SaleInviteDoctorOrderPageRes> iPage = req.pagePojo();
        iPage = getBaseMapper().querySaleInviteDoctorOrderPage(iPage, req);
        return iPage;
    }

    /**
     * @param req:
     * @return SaleInviteDoctorStatisticsRes
     * @description 销售首页, 统计邀请医生数量 按周,月,指定时间等等
     * @author czg
     * @date 2023/6/27 17:06
     */
    @Override
    public SaleInviteDoctorStatisticsRes querySaleDoctorStatistics(SaleInviteDoctorStatisticsReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        SaleInviteDoctorStatisticsReq.SaleInviteDoctorStatisticsQuery query = new SaleInviteDoctorStatisticsReq.SaleInviteDoctorStatisticsQuery();
        SaleInviteDoctorStatisticsReq.SaleInviteDoctorStatisticsColQuery colQuery = new SaleInviteDoctorStatisticsReq.SaleInviteDoctorStatisticsColQuery();
        query.setSaleId(loginInfo.getId());
        colQuery.setSaleId(loginInfo.getId());
        LocalDate now = LocalDate.now();
        switch (req.getDayType()) {
            case "week":
                query.setNum(6);
                colQuery.setEDay(DateUtils.todayEndTime(now));
                colQuery.setSDay(DateUtils.getStartTimeOfDay(now.plusDays(-6)));
                colQuery.setLeDay(DateUtils.todayEndTime(now.plusDays(-7)));
                colQuery.setLsDay(DateUtils.getStartTimeOfDay(now.plusDays(-13)));
                break;
            case "month":
                //相差天数
                long dayNum = LocalDate.now().toEpochDay() - DateUtils.getFirstDayOfMonth(LocalDate.now()).toLocalDate().toEpochDay();
                query.setNum((int) dayNum + 1);
                colQuery.setSDay(DateUtils.getFirstDayOfMonth(now));
                colQuery.setEDay(DateUtils.getLastDayOfMonth(now));
                colQuery.setLsDay(DateUtils.getFirstDayOfMonth(now.minusMonths(1)));
                colQuery.setLeDay(DateUtils.getLastDayOfMonth(now.minusMonths(1)));
                break;
            case "perMonth":
                query.setNode("month");
                colQuery.setSDay(DateUtils.getFirstDayOfMonth(now));
                colQuery.setEDay(DateUtils.getLastDayOfMonth(now));
                break;
            case "customDay":
                if (req.getStartDay() == null || req.getEndDay() == null) {
                    throw new ZekeException("请选择开始日期和结束日期");
                }
                dayNum = req.getEndDay().toEpochDay() - req.getStartDay().toEpochDay();
                //相差天数
                query.setNum((int) dayNum + 1);
                query.setStartDay(req.getEndDay());
                colQuery.setSDay(DateUtils.getStartTimeOfDay(req.getStartDay()));
                colQuery.setEDay(DateUtils.todayEndTime(req.getEndDay()));
        }
        SaleInviteDoctorStatisticsRes res = getBaseMapper().querySaleDoctorStatisticsNum(colQuery);
        List<SaleInviteDoctorStatisticsRes.DoctorStatisticsDayRes> doctorStatisticsDayRes = getBaseMapper().querySaleDoctorStatistics(query);
        Integer total = 0;
        if ("perMonth".equals(req.getDayType())) {
            doctorStatisticsDayRes = doctorStatisticsDayRes.stream().map(item -> {
                item.setDate(item.getDate().substring(0, item.getDate().lastIndexOf("-")));
                return item;
            }).collect(Collectors.toList());
            for (SaleInviteDoctorStatisticsRes.DoctorStatisticsDayRes result : doctorStatisticsDayRes) {
                total = total + Integer.valueOf(result.getNum());
            }
            res.setNum(String.valueOf(total));
        }
        res.setDayRes(doctorStatisticsDayRes);
        return res;
    }

}
